﻿using System;
using System.Threading;


class PopCorn
{
    static int ballX;
    static int ballY;
    static int padX;
    static int padY;
    static int padSize = 9;
    static char padSymbol = 'x';
    static int livesCount = 5;

    static int[] horizontal;
    static int[] vertical;
    static int currentDirectionX;
    static int currentDirectionY;

    static int[,] bricks;
    static int countBricks;

    static int gameScore;

    static void GameSettings()
    {
        Console.Title = "PopCorn Game";
        Console.BufferWidth = Console.WindowWidth = 40;
        Console.BufferHeight = Console.WindowHeight = 45;

        ballX = 17;
        ballY = 30;

        padX = Console.WindowWidth / 2;
        padY = Console.WindowHeight - 1;

        currentDirectionX = 0;
        currentDirectionY = 0;
        horizontal = new int[] { -1, 1 };
        vertical = new int[] { -1, 1 };

        bricks = new int[Console.WindowWidth, Console.WindowHeight];
        countBricks = 0;

        gameScore = 0;
    }

    static void DrawScore()
    {
        Console.SetCursorPosition(0, 0);
        Console.ForegroundColor = ConsoleColor.Gray;
        Console.Write("Score: " + gameScore + "      Number of bricks: " + countBricks);
    }

    static void DrawLives()
    {
        Console.SetCursorPosition(0,2);
        Console.ForegroundColor = ConsoleColor.DarkYellow;
        Console.Write("Lives: " + livesCount);
    }

    static void InitalBricks()
    {
        for (int i = 10; i < 30; i++)
		{
			 for (int j = 10; j< i; j++)
			{
			 bricks[i,j] = 1;
			}
		}

        for (int i = 20; i >= 5; i--)
        {
            for (int j = 5; j < i; j++)
            {
                bricks[j, i] = 1;
            }
        }
    }

    static void DrawBricks()
    {
        for (int i = 0; i < bricks.GetLength(0); i++)
			{
			     for (int j = 0; j < bricks.GetLength(1); j++)
			    {
			        if (bricks[i,j] == 1)
	                {
                        Random rand = new Random();
                        int brick = rand.Next(0,51);

                        if (brick == 10 || brick == 20 || brick == 30 || brick == 40 || brick == 50)
                        {
                            Console.SetCursorPosition(i, j);
                            Console.ForegroundColor = ConsoleColor.Gray;
                            Console.Write('#');
                        }
                        else if (brick == 5 || brick == 15 || brick == 25 || brick == 35 || brick == 45)
                        {
                            Console.SetCursorPosition(i, j);
                            Console.ForegroundColor = ConsoleColor.DarkYellow;
                            Console.Write('#');
                        }
                        else if (brick == 1 || brick == 3 || brick == 7 || brick == 9 || brick == 11)
                        {
                            Console.SetCursorPosition(i, j);
                            Console.ForegroundColor = ConsoleColor.Blue;
                            Console.Write('#');
                        }
                        else
                        {
                            Console.SetCursorPosition(i, j);
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.Write('#');
                        }
                        countBricks++;
	                }
			    }
			}
    }

    static void MoveBall()
    {
        Console.SetCursorPosition(ballX,ballY);
        Console.Write(' ');
        ballX+= horizontal[currentDirectionX];
        ballY+= vertical[currentDirectionY];
        DrawBall();
    }

    static void DrawBall()
    {
        Console.SetCursorPosition(ballX, ballY);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write('O');
    }

    static void CollisionWithWall()
    {
        if (ballX < 2)
        {
            ChangeXDirection();
        }
        if (ballX > Console.WindowWidth - 2)
        {
            ChangeXDirection();
        }
        if (ballY < 2)
        {
            ChangeYDirection();
        }
        if (ballY > Console.WindowHeight - 2)
        {
            throw new IndexOutOfRangeException();
        }
    
    }

    static void CollisionWithPad()
    {
        if (ballY + 1 == padY && ballX >= padX && ballX <= padX + padSize )
        {
            ChangeYDirection();
        }
    }

    static void CollisionWithBricks()
    {
        if (bricks[ballX, ballY - 1] == 1)
        {
            bricks[ballX, ballY - 1] = 0;
            countBricks--;
            gameScore += 10;
            Console.SetCursorPosition(ballX, ballY - 1);
            Console.Write(' ');
            ChangeYDirection();
        }
        if (bricks[ballX, ballY + 1] == 1)
        {
            bricks[ballX, ballY + 1] = 0;
            countBricks--;
            gameScore += 10;
            Console.SetCursorPosition(ballX, ballY + 1);
            Console.Write(' ');
            ChangeYDirection();
        }
        if (bricks[ballX + 1, ballY] == 1)
        {
            bricks[ballX + 1, ballY] = 0;
            countBricks--;
            gameScore += 10;
            Console.SetCursorPosition(ballX + 1, ballY);
            Console.Write(' ');
            ChangeXDirection();
        }
        if (bricks[ballX - 1, ballY] == 1)
        {
            bricks[ballX - 1, ballY] = 0;
            countBricks--;
            gameScore += 10;
            Console.SetCursorPosition(ballX - 1, ballY);
            Console.Write(' ');
            ChangeXDirection();
        }
    
    }

    static void ChangeXDirection()
    {
        if (currentDirectionX == 0)
        {
            currentDirectionX = 1;
        }
        else
        {
            currentDirectionX = 0;
        }
    }

    static void ChangeYDirection()
    {
        if (currentDirectionY == 0)
        {
            currentDirectionY = 1;
        }
        else
        {
            currentDirectionY = 0;
        }
    }

    static void DrawPad()
    {
        for (int i = padX; i < padX + padSize; i++)
        {
            Console.SetCursorPosition(i, padY);
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write(padSymbol);
        }
    }

    static void MovePad()
    {
        if (Console.KeyAvailable)
        {
            ConsoleKeyInfo key = Console.ReadKey();
            while (Console.KeyAvailable)
            {
                Console.ReadKey();
            }

            
                if (key.Key == ConsoleKey.LeftArrow)
                {
                    if (padX > 0)
                    {
                        padX--;
                        Console.SetCursorPosition(padX + padSize, padY);
                        Console.Write(' ');
                        DrawPad();
                    }
                }

                if (key.Key == ConsoleKey.RightArrow)
                {
                    if (padX + padSize < Console.WindowWidth - 1)
                    {
                        padX++;
                        Console.SetCursorPosition(padX - 1, padY);
                        Console.Write(' ');
                        DrawPad();
                    }
                }       
        }
    
    }

    static void GameOver()
    {
        Console.Clear();
        Console.SetCursorPosition(Console.WindowWidth/2 - 4, Console.WindowHeight/2);
        Console.ForegroundColor = ConsoleColor.Red;
        Console.CursorVisible = false;
        Console.Write("GAME OVER!");
        Console.ReadLine();
    }


    static void Engine()
    {       
        InitalBricks();
        DrawBricks();
        DrawPad();
        
        
        
        while (countBricks > 0)
        {
            try
            {
                CollisionWithWall();
            }
            catch (IndexOutOfRangeException)
            {
                livesCount--;

                Console.Clear();

                ballX = 17;
                ballY = 30;

                gameScore = 0;
                DrawScore();
                DrawLives();
                InitalBricks();
                DrawBall();
                DrawBricks();
                DrawPad();

                if (livesCount == 0)
                {
                    GameOver();
                    break;
                }
                else
                {
                    ChangeYDirection();
                }        
            }

            if(ballX - 1 > 0 && ballX + 1 < Console.WindowWidth - 1 && ballY - 1 > 0 && ballY + 1<Console.WindowHeight - 1)
            {
                CollisionWithBricks();
            }

            CollisionWithPad();
            DrawScore();
            DrawLives();
            MoveBall();
            MovePad();
            Thread.Sleep(55);
        }
        GameOver();
    }

    static void Main()
    {
       
        GameSettings();
        Engine();
        
    }
}

